package com.kins.executer.handlers.common.base;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONPath;
import com.kins.executer.constants.Constant;
import com.kins.executer.constants.DataConstant;
import com.kins.executer.entitys.SOFlowRectsEntity;
import com.kins.executer.utils.DataUtils;
import com.kins.executer.vo.MappingParamVo;
import io.micrometer.common.util.StringUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @Description:
 * 执行接口拦截器
 * @Author: 申科
 * @Date:2025/11/11 20:38
 */
@Component
public abstract class ExecuterHandler extends BaseHandler{
    @Value("${execute.config.retry-count}")
    private int retryCount;

    @Value("${execute.config.retry-count}")
    private int retryCount1;
    public static final Logger logger = LoggerFactory.getLogger(ExecuterHandler.class);
    /**
     * 主执行方法
     */
    public void execute(Map<String, Object> dataMap, MappingParamVo vo) throws Exception{
        retryCount = retryCount1;
        dataMap.put(Constant.START_DATE_KEY, System.currentTimeMillis());
        //是否冲正，根据so_flow_rect表中rush_service是否有值进行判断
        String lj = DataUtils.getJoinStr(Constant.COLON, Constant.RECTS_MAP,DataUtils.getRectsKeyStr(vo));
        SOFlowRectsEntity soFlowRectsEntity = (SOFlowRectsEntity) DataUtils.getParamValue(dataMap,lj,Constant.COLON);
        boolean isRighting = soFlowRectsEntity != null ? soFlowRectsEntity.getIsRighting() : false;
        //重试次数
        //是否冲正接口
        String isRightInterface = (String) dataMap.get(Constant.IS_RIGHTING_KEY);
        Map<String, Object> inputMap = null;
        try{
            //获取入参
            inputMap = getInputParam(vo);
            inputMap.put(DataConstant.INPUTDATA_BUSINESSNO, MapUtils.getString(dataMap,DataConstant.INPUTDATA_BUSINESSNO));
            inputMap.put(DataConstant.INPUTDATA_ORGCODE,MapUtils.getString(dataMap,DataConstant.INPUTDATA_ORGCODE));
            replaceValue(inputMap);
        }catch (Exception e){
            String info = Constant.RUN_ERROR_ONE + e.getMessage();
            info = ParamLogUtils.setLogInfo(vo,info);
            logger.error(info);
            throw e;
        }
        //输入数据对象
        Map<String, Object> inMap = new HashMap<>();
        try{
            if(inputMap != null){
                inMap.putAll(inputMap);
            }
            inMap.put(Constant.START_DATE_KEY, System.currentTimeMillis());
            inMap.put(Constant.RUN_INFO_KEY, Constant.START_RUN);
            inMap.put(Constant.RUNFLOW_ID,vo.getDataMap().get(Constant.RUNFLOW_ID));
            //执行返回出惨
            Map<String, Object> returnMap = retry(vo,inputMap);
            //获取返回结果
            String status = (String) returnMap.get(Constant.ACTION_KEY);
            //日志的默认描述信息
            String returnInfo = Constant.END_RUN;
            //失败
            if(!Constant.SUCCESS_STATUS.equals(status)){
                returnInfo = Constant.RUN_ERROR_ONE + returnMap.get(Constant.ACTIONINFO_KEY);
                vo.setNodeType(Constant.NODE_TYPE_0);
                //需要调用之前的冲正交易
                dataMap.put(Constant.IS_RIGHTING_KEY, Constant.IS_RIGHTING_KEY_1);
                new RightingInterfaceExecuterHandler(vo).execute(dataMap);
                dataMap.put(Constant.IS_RIGHTING_KEY, Constant.IS_RIGHTING_KEY_0);
            }else{
                //当前接口成功了，才应该把当前的冲正接口放入
                if(isRighting){
                    vo.setRightingInterfaceId(soFlowRectsEntity.getRushService());
                    vo.setRightingInterfaceVersion(soFlowRectsEntity.getRushVersion());
                    vo.setRightingInterfaceType(soFlowRectsEntity.getRushType());
                    //将冲正接口ID插入栈中
                    RightingUtils.setRightingInfo(vo);
                }
                dataMap.put(Constant.IS_RIGHTING_KEY, Constant.IS_RIGHTING_KEY_0);
                getOutParam(dataMap,inMap,returnMap);//出参信息映射处理方法
            }
            //结果数据存入上下文
            ParamLogUtils.setParamValueLog(vo, inMap,DataUtils.supplyData(returnMap,returnInfo,
                    isRightInterface, inMap.get(Constant.START_DATE_KEY)));
        }catch (Exception e){
            String info = ParamLogUtils.setLogInfo(vo,e);//dataMap中保存日志信息
            logger.error(info);
            ParamLogUtils.setParamValueLog(vo,inMap,DataUtils.supplyData(new HashMap<>(),info,
                    isRightInterface,inMap.get(Constant.START_DATE_KEY)));
            //报错时 需要进行冲正接口的调用
            //需要调用冲正交易
            if(isRighting){
                dataMap.put(Constant.IS_RIGHTING_KEY, Constant.IS_RIGHTING_KEY_1);
                new RightingInterfaceExecuterHandler(vo).execute(dataMap);//冲正交易
                dataMap.put(Constant.IS_RIGHTING_KEY, Constant.IS_RIGHTING_KEY_0);
            }else {
                throw e;
            }
        }
    }
    /**
     * 入参信息映射处理
     */
    private Map<String, Object> getInputParam(MappingParamVo vo) throws Exception{
        vo.setIsOut(BaseParamEnum.IN_PARAM.getCode());
        vo.setIsService(BaseParamEnum.IS_INTERFACE.getType());
        return ParamUtils.changeMappingMap(vo);
    }

    /**
     * 出参信息映射处理方法
     */
    private Map<String, Object> getOutParam(Map<String, Object> dataMap, Map<String, Object> inputMap, Map<String, Object> returnMap) throws Exception{
        return dataMap;
    }

    /**
     * 重试调用执行方法，用于报错后可重复调用
     */

    private Map<String, Object> retry(MappingParamVo vo, Map<String, Object> inputMap) throws Exception{
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put(Constant.ACTION_KEY,Constant.NO_SUCCESS_STATUS);
        boolean isRetry = true;
        while(isRetry && retryCount >=0){
            retryCount--;
            returnMap = exe(inputMap,vo);
            //获取返回状态
            String status = (String) returnMap.get(Constant.ACTION_KEY);
            if(Constant.SUCCESS_STATUS.equals(status)){
                isRetry = false;
            }
        }
        return returnMap;
    }
    /**各执行类型所需要实现的方法
     * 执行方法
     */
    public abstract Map<String, Object> exe(Map<String, Object> inputMap, MappingParamVo vo) throws Exception;

    public Map<String, Object> initMap(){
        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put(Constant.ACTION_KEY,Constant.NO_SUCCESS_STATUS);
        returnMap.put(Constant.ACTIONINFO_KEY,ReturnCodeEnum.SUCCESS.getDesc());
        return returnMap;
    }

    public void replaceValue(Map<String, Object> inputMap){
        if(inputMap == null || inputMap.size() <=0){
            return;
        }
        Pattern pattern = Pattern.compile("\\{\\{(.*?)\\}\\}");
        String json = JSON.toJSONString(inputMap);
        for (Map.Entry<String, Object> s : inputMap.entrySet()){
            String keyValue = String.valueOf(s.getValue());
            StringBuffer sb = new StringBuffer();
            Matcher matcher = pattern.matcher(keyValue);
            Boolean haveTemplate = false;
            while (matcher.find()){
                haveTemplate = true;
                try{
                    String key = matcher.group(1);
                    String value = JSON.toJSONString(JSONPath.read(json,key));
                    value = StringUtils.strip( value,"\"\"");
                    matcher.appendReplacement(sb,value);
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
            matcher.appendTail(sb);
            if(haveTemplate){
                inputMap.put(s.getKey(),sb.toString());
            }
        }
    }

}
